/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package models;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import play.data.validation.Required;
import play.db.jpa.Model;

/**
 * 
 * @author Ousama
 */
@Entity
public class ActionPlan extends Model {

    @Required
    public String name;
    public String description;
    public String requirment;
    public String status;
    public Date startDate;
    public Date endDate;
    public long organizationId;
    public int views = 0;
    public Timeline timeline;
    @OneToMany(mappedBy = "actionPlan", cascade = CascadeType.ALL)
    public List<Comment> comments = new ArrayList<Comment>();
    @ManyToMany(mappedBy = "managedActionPlane", cascade = CascadeType.PERSIST)
    public List<Organizer> managers = new ArrayList<Organizer>();
    @OneToMany(mappedBy = "ideaPlan", cascade = CascadeType.ALL)
    public List<Idea> ideas = new ArrayList<Idea>();
    @ManyToMany(mappedBy = "volunteer", cascade = CascadeType.PERSIST)
    public List<IdeaDeveloper> volunteers = new ArrayList<IdeaDeveloper>();
    @OneToMany(mappedBy = "actionPlan", cascade = CascadeType.ALL)
    public List<ActionItem> actionItems = new ArrayList<ActionItem>();
    @OneToMany(mappedBy = "actionPlan", cascade = CascadeType.ALL)
    public List<Rate> rates = new ArrayList<Rate>();

    /**
     * this is a contructor for the action plan
     *
     * @author Amr Gaml
     * @param name
     *            name of the action plan
     * @param body
     *            body of the action plan
     * @param requirment
     *            requirment of the action plan
     * @param status
     *            status of the action plan
     * @param startDate
     *            satrtDate of the action plan
     * @param endDate
     *            endDate of the action plan
     * @param organizationId
     *            Id of the organization of the action plan
     */
    public ActionPlan(String name, String body, String requirment,
            String status, Date startDate, Date endDate, long organizationId) {

        this.name = name;
        this.description = body;
        this.requirment = requirment;
        this.status = status;
        this.startDate = startDate;
        this.endDate = endDate;
        this.organizationId = organizationId;
        this.views = 0;

        Log log = new Log("Action Plan ^ was created in ^.");
        log.ids = this.id + "," + this.organizationId;
        log.types = "actionplan,organization";
        log.save();

    }

    /**
     * Empty Constructor for initializing Action Plan
     *
     * @author
     */
    public ActionPlan() {
    }

    /**
     * Helper to delete the action plan and all its components
     *
     * @author
     */
    public void delete2(long doerId) {

        // delete it from the voluntering list
        IdeaDeveloper ideaDev = IdeaDeveloper.findById(doerId);
        for (int i = 0; i < volunteers.size(); i++) {
            Notification.notify(" has deleted " + this.name + " ",
                    volunteers.get(i), ideaDev, new Date());
            volunteers.get(i).volunteer.remove(this);
            volunteers.get(i).save();
        }

        // delete all the comments in it
        while (!comments.isEmpty()) {
            Notification.notify(" has deleted " + this.name + " ",
                    comments.get(0).creator,
                    ideaDev, new Date());
            comments.get(0).delete2();

        }

        // nothing to be managed here anymore
        for (int i = 0; i < managers.size(); i++) {
            if (managers.get(i).ideaDeveloper.id != doerId) {
                Notification.notify(" has deleted "
                        + this.name + " ",
                        managers.get(i).ideaDeveloper, ideaDev, new Date());
            }
            managers.get(i).managedActionPlane.remove(this);
            managers.get(i).save();
        }

        // delete its ideas
        while (!ideas.isEmpty()) {
            Notification.notify(" has deleted " + this.name + " ",
                    ideas.get(0).creator, ideaDev,
                    new Date());
            ideas.get(0).delete2();
        }

        // no more actionItems in here
        while (!actionItems.isEmpty()) {
            actionItems.get(0).delete2(doerId);
        }

        while (!rates.isEmpty()) {
            rates.get(0).delete2();
        }

        Log log = new Log("^ deleted ^.");
        log.ids = doerId + "," + this.id;
        log.types = "developer,actionplan";
        log.save();
        this.delete();


    }

    /**
     * this methods gets the organization of the Idea
     *
     * @author Doaa
     * @param idea
     *            the idea wanting to get its parent organization
     * @return OrganizationId the organization where the idea lies
     */
    public static long getIdeasOrganization(Idea idea) {

        long orgId = -1;

        if (idea.ideaOrg != null) {

            orgId = idea.ideaOrg.id;

        } else if (idea.ideaEnt != null) {

            orgId = idea.ideaEnt.liesIn.id;

        } else if (idea.ideaTopic != null) {

            Topic t = idea.ideaTopic;

            if (t.topicOrg != null) {

                orgId = t.topicOrg.id;

            } else if (t.topicEnt != null) {

                Entities e = t.topicEnt;
                orgId = e.liesIn.id;

            }

        }

        return orgId;

    }

    /**
     * this methods gets the follower of the topic/entity/organization where the
     * idea exist
     *
     * @author Doaa
     * @param Idea
     *            idea the idea that action plan was started with
     *
     */
    public List<IdeaDeveloper> getFollowers(Idea idea) {

        List<IdeaDeveloper> followers = null;

        if (idea.ideaTopic != null) {

            followers = idea.ideaTopic.followed;

        } else {

            if (idea.ideaEnt != null) {

                followers = idea.ideaEnt.followed;

            } else {

                if (idea.ideaOrg != null) {

                    followers = idea.ideaOrg.followed;
                }
            }

        }

        return followers;

    }

    /**
     * @author Amr Gamal
     * a method that returns the followers of ideas related to an action plan
     * @return List<IdeaDeveloper>
     * 							 a list of the ideaDevelopers who follows the plan
     */
    public List<IdeaDeveloper> getPlanFollowers() {
        List<Idea> planIdeas = this.ideas;

        List<IdeaDeveloper> planFollowers = new ArrayList<IdeaDeveloper>();
        for (int i = 0; i < planIdeas.size(); i++) {
            List<IdeaDeveloper> ideaFollowers = this.getFollowers(planIdeas.get(i));
            for (int j = 0; j < ideaFollowers.size(); j++) {
                planFollowers.add(ideaFollowers.get(j));

            }
        }
        return planFollowers;
    }
}
